﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml.Linq;
using ChinaDynastyTours.Controls;
using ChinaDynastyTours.Models;
using DevExpress.Utils;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using ChinaDynastyTours.Helpers;

namespace ChinaDynastyTours.Views
{
    public partial class GuideStatusForm : DevExpress.XtraEditors.XtraForm
    {
        private DateTime _CurrentSelectDate;
        private DataTable _dtGuideArrangeInfo;

        private DateTime _StartDate,_EndDate;

        public GuideStatusForm()
        {
            InitializeComponent();
        }

        private void GuideStatusForm_Load(object sender, EventArgs e)
        {
            tbSelectedDate.EditValue = DateTime.Now;
            foreach (DataRow dr in BaseInfoCtrl.GetCiceroniLanguageData().Rows)
                tbLanguageEdit.Items.Add(dr[0]);
        }

        private void btnRefresh_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            _CurrentSelectDate = DateTime.Parse(tbSelectedDate.EditValue.ToString());

            _StartDate = new DateTime(_CurrentSelectDate.Year, _CurrentSelectDate.Month, 1);
            _EndDate = new DateTime(_CurrentSelectDate.Year, _CurrentSelectDate.Month, DateTime.DaysInMonth(_CurrentSelectDate.Year, _CurrentSelectDate.Month));

            LoadGuideArrangeLayout();
        }
        private void LoadGuideArrangeLayout()
        {
            //根据导游语言筛选导游，并生成网格
            string language = tbLanguage.EditValue == null ? "" : tbLanguage.EditValue.ToString();

            DataTable tmpDt = BaseInfoCtrl.GetCiceroniNameData(language, ApplicationHelper.CurrentLoginProviderNameAndID[1]);

            for (int i = 0; i < (_EndDate - _StartDate).Days + 1; i++)
            {
                tmpDt.Columns.Add(_StartDate.AddDays(i).ToString("yyyy-MM-dd")).Caption = _StartDate.AddDays(i).ToString("MM\ndd");//_StartDate.AddDays(i).Day.ToString();
            }
            guideStatusGridView.Columns.Clear();
            guideStatusGridControl.DataSource = tmpDt;
            for (int i = 0; i < (_EndDate - _StartDate).Days + 1; i++)
                guideStatusGridView.Columns[_StartDate.AddDays(i).ToString("yyyy-MM-dd")].Width = 35;

            guideStatusGridView.Columns["CiceroniID"].Visible = false;              //导游CiceroniID列不显示
            guideStatusGridView.Columns["CiceroniName"].Caption = "姓名";
            guideStatusGridView.Columns["CiceroniName"].Width = 50;


            //根据月份获取已经安排的导游信息
            _dtGuideArrangeInfo = GuideArrangeCtrl.GetGuideArrangeData(_StartDate, _EndDate);//_CurrentSelectDate);
            if (_dtGuideArrangeInfo == null) return;

            foreach (DataRow dr in _dtGuideArrangeInfo.Rows) //循环导游安排信息
            {
                DataRow[] tmpDr = tmpDt.Select(string.Format("CiceroniID={0}", dr["CiceroniID"].ToString()));//将已安排导游ID做为过滤条件，找到将要赋值的行
                if (tmpDr != null && tmpDr.Length > 0)
                {
                    DateTime start = DateTime.Parse(dr["StartDate"].ToString());
                    DateTime end = DateTime.Parse(dr["EndDate"].ToString());

                    int days = (end - start).Days + 1;//int.Parse(end.ToString("dd")) - int.Parse(start.ToString("dd"))+1;
                    for (int i = 0; i < days; i++)
                    {
                        //察看事件类型，是事假则赋值0
                        switch (dr["HasEvent"].ToString())
                        {
                            case "1"://事假
                                if (i == 0)//是否为起始位置
                                    tmpDr[0][start.AddDays(i).ToString("yyyy-MM-dd")] = "#0";
                                else
                                    tmpDr[0][start.AddDays(i).ToString("yyyy-MM-dd")] = "0";
                                break;
                            case "5"://紧急事件
                                if (i == 0)
                                    tmpDr[0][start.AddDays(i).ToString("yyyy-MM-dd")] = "#5";
                                else
                                    tmpDr[0][start.AddDays(i).ToString("yyyy-MM-dd")] = "5";
                                break;
                            default:
                                string cellValue = tmpDr[0][start.AddDays(i).ToString("yyyy-MM-dd")].ToString();//察看界面是否已经有赋值，存在多次上团的可能性
                                if (cellValue == "")//表明还没有标记，此次为导游一天内第1次上团
                                {
                                    if (i == 0)
                                        tmpDr[0][start.AddDays(i).ToString("yyyy-MM-dd")] = "#1";
                                    else
                                        tmpDr[0][start.AddDays(i).ToString("yyyy-MM-dd")] = "1";
                                    continue;
                                }
                                if (cellValue == "1")//表明还没有标记，此次为导游一天内重复第2次上团
                                {
                                    if (i == 0)
                                        tmpDr[0][start.AddDays(i).ToString("yyyy-MM-dd")] = "#2";
                                    else
                                        tmpDr[0][start.AddDays(i).ToString("yyyy-MM-dd")] = "2";
                                    continue;
                                }
                                if (cellValue == "2")//表明还没有标记，此次为导游一天内重复第3次上团
                                {
                                    if (i == 0)
                                        tmpDr[0][start.AddDays(i).ToString("yyyy-MM-dd")] = "#3";
                                    else
                                        tmpDr[0][start.AddDays(i).ToString("yyyy-MM-dd")] = "3";
                                    continue;
                                }
                                break;
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 选择计划
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSelect_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            new GuideArrangeForm(DateTime.Parse(tbSelectedDate.EditValue.ToString())).ShowDialog(this);
            //btnRefresh.PerformClick();
        }

        #region 快捷菜单


        /// <summary>
        /// 导游事假标注菜单项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mnuEvent_Click(object sender, EventArgs e)
        {
            int rowIndex = -1;
            //string xmlCalendar = "";

            ToolStripMenuItem mnuItem = (sender as ToolStripMenuItem);

            GuideStatusSelectedTool frm = new GuideStatusSelectedTool();
            frm.Location = DevExpress.Utils.ControlUtils.CalcLocation(Control.MousePosition, Control.MousePosition, frm.Size);
            frm.Text = mnuItem.Name == "mnuLeaveEvent" ? "请填写导游事由内容" : "请填写紧急事件内容";
            if (frm.ShowDialog() == DialogResult.OK)
            {
                GridCell[] selectedCells = guideStatusGridView.GetSelectedCells();
                Dictionary<int, Dictionary<string, GridCell>> selectedRowData = new Dictionary<int, Dictionary<string, GridCell>>();
                Dictionary<string, GridCell> CellData = null;

                foreach (GridCell cell in selectedCells)
                {
                    guideStatusGridView.SetRowCellValue(cell.RowHandle, cell.Column, 1);
                    if (rowIndex != cell.RowHandle)
                    {
                        CellData = new Dictionary<string, GridCell>();
                        selectedRowData.Add(cell.RowHandle, CellData);
                    }
                    CellData.Add(cell.Column.FieldName, cell);
                    //CellData.Add(DateTime.Parse(string.Format("{0}-{1}-{2}", _CurrentSelectDate.Year, _CurrentSelectDate.Month, cell.Column.FieldName)).ToString("yyyy-MM-dd"), cell);

                    rowIndex = cell.RowHandle;
                }

                List<GuideArrangeEntity> entities = new List<GuideArrangeEntity>();

                //初始化多条导游事假数据内容，并写入数据库
                //GuideArrangeEntity entity = new GuideArrangeEntity();

                foreach (var item in selectedRowData)
                {
                    //xmlCalendar = "";
                    int i = 0;

                    GuideArrangeEntity entity = new GuideArrangeEntity();
                    foreach (var subItem in item.Value)
                    {
                        if (i == 0)//取第一个日期
                            entity.StartDate = subItem.Key;
                        if (i == item.Value.Values.Count - 1)//取最后一个的日期
                            entity.EndDate = subItem.Key;

                        //xmlCalendar = CreateXMLCalendar(xmlCalendar, subItem.Key);//将第一个、最后一个以及中间的日历号全部存储
                        i++;
                    }
                    entity.Calendars = "";//xmlCalendar;
                    entity.CiceroniName = guideStatusGridView.GetRowCellValue(item.Key, "CiceroniName").ToString();//获取指定行的第一列导游‘姓名’
                    entity.CiceroniID = int.Parse(guideStatusGridView.GetRowCellValue(item.Key, "CiceroniID").ToString());
                    entity.TourgroupID = "";
                    entity.Notified = false;
                    entity.HasEvent = mnuItem.Name == "mnuLeaveEvent" ? 1 : 5;//1代表事件信息，5代表紧急事件
                    entity.Remark = frm.tbContext.Text;

                    entities.Add(entity);
                }
                if (entities.Count > 0)
                    GuideArrangeCtrl.CreateGuideArrangeData(entities);
                btnRefresh.PerformClick();
            }
        }

        /// <summary>
        /// 删除标注单元格
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mnuDelete_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("确认删除选中行的导游安排信息？", "删除确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                int rowIndex = -1;

                GridCell[] selectedCells = guideStatusGridView.GetSelectedCells();
                Dictionary<int, Dictionary<string, GridCell>> selectedRowData = new Dictionary<int, Dictionary<string, GridCell>>();
                Dictionary<string, GridCell> CellData = null;

                foreach (GridCell cell in selectedCells)
                {
                    //guideStatusGridView.SetRowCellValue(cell.RowHandle, cell.Column, 1);
                    if (rowIndex != cell.RowHandle)
                    {
                        CellData = new Dictionary<string, GridCell>();
                        selectedRowData.Add(cell.RowHandle, CellData);
                    }
                    CellData.Add(cell.Column.FieldName, cell);

                    rowIndex = cell.RowHandle;
                }
                //初始化一条导游安排数据内容，并写入数据库
                foreach (var item in selectedRowData)
                {
                    int i = 0;
                    foreach (var subItem in item.Value)
                    {
                        //单元格的日期
                        //string yMd = DateTime.Parse(string.Format("{0}-{1}-{2}", _CurrentSelectDate.Year, _CurrentSelectDate.Month, subItem.Key)).ToString("yyyy-MM-dd");
                        string ciceroniId = guideStatusGridView.GetRowCellValue(item.Key, "CiceroniID").ToString();

                        //根据单元格日期及导游ID获取安排信息
                        DataTable tmpDt = GuideArrangeCtrl.GetGuideArrangeData(subItem.Key, ciceroniId);
                        if (tmpDt.Rows.Count > 0)
                        {
                            string id = tmpDt.Rows[0]["GuideArrangeID"].ToString();

                            #region 注释—原删除或更新单元格方法，保留
                            //string xmlDocResult = "";
                            //bool retValue = DeleteXMLCalendar(tmpDt.Rows[0]["Calendars"].ToString(), subItem.Key, out xmlDocResult);
                            //if (retValue == true)//还存在内容
                            //    GuideArrangeCtrl.UpdateCalendarsData(xmlDocResult, id);
                            //else
                            //    GuideArrangeCtrl.DeleteGuideArrangeData(id); 
                            #endregion

                            //直接删除选中的一个安排（选中一个cell，删除‘一行’数据）
                            GuideArrangeCtrl.DeleteGuideArrangeData(id);
                        }
                        i++;
                    }
                }
                btnRefresh.PerformClick();
            }
        }


        /// <summary>
        /// 上下文菜单显示控制
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mnuGuideStatus_Opening(object sender, CancelEventArgs e)
        {
            //导游性名列不允许选择
            GridCell[] selectedCells = guideStatusGridView.GetSelectedCells();
            string[] cellValue = new string[selectedCells.Length];

            for (int i = 0; i < selectedCells.Length; i++)
                cellValue[i] = guideStatusGridView.GetRowCellValue(selectedCells[i].RowHandle, selectedCells[i].Column).ToString();

            if (!cellValue.Contains("0") && !cellValue.Contains("#0") && !cellValue.Contains("1") && !cellValue.Contains("#1") && !cellValue.Contains("2") && !cellValue.Contains("#2") && !cellValue.Contains("3") && !cellValue.Contains("#3") && !cellValue.Contains("5") && !cellValue.Contains("#5"))
            {
                mnuLeaveEvent.Visible = true;
                mnuEmergencyEvent.Visible = true;
                mnuSeparator.Visible = false;
                mnuDelete.Visible = false;
            }
            else
            {
                mnuLeaveEvent.Visible = false;
                mnuEmergencyEvent.Visible = false;
                mnuSeparator.Visible = false;
                mnuDelete.Visible = true;
            }
        }
        #endregion

        #region 日历xml数据处理

        /// <summary>
        /// 生成‘中间日历号’xml节点内容
        /// </summary>
        /// <param name="xmlCalendar">xml内容</param>
        /// <param name="value">日历号，如 5</param>
        /// <returns>增加节点后的xml内容</returns>
        private static string CreateXMLCalendar(string xmlCalendar, object value)
        {
            using (StringReader sr = new StringReader(xmlCalendar == "" ? @"<Root/>" : xmlCalendar))
            {
                XDocument xmlDoc = XDocument.Load(sr);
                XElement xe = new XElement("Calendar", value);
                xmlDoc.Root.Add(xe);
                sr.Close();
                return xmlDoc.ToString();
            }
        }
        /// <summary>
        /// 删除指定日历号的xml节点
        /// </summary>
        /// <param name="xmlCalendar">xml内容</param>
        /// <param name="value">日历号，如 5</param>
        /// <param name="xmlDocResult">返回删除节点后的xml内容</param>
        /// <returns>true还存在节点，false不存在节点了</returns>
        private static bool DeleteXMLCalendar(string xmlCalendar, string value, out string xmlDocResult)
        {
            xmlDocResult = "";
            using (StringReader sr = new StringReader(xmlCalendar == "" ? @"<Root/>" : xmlCalendar))
            {
                XDocument xmlDoc = XDocument.Load(sr);
                var e = xmlDoc.Descendants("Calendar").Where(x => x.Value == value);//.Single();
                if (e.Count() > 0)
                    e.Remove();

                sr.Close();
                xmlDocResult = xmlDoc.ToString();

                return xmlDoc.Root.Nodes().Count() > 0;
            }
        }
        /// <summary>
        /// 解析日历信息
        /// </summary>
        /// <param name="xmlCalendar">xml内容</param>
        /// <returns>日历数组</returns>
        private static string[] ParseXMLCalendar(string xmlCalendar)
        {
            if (xmlCalendar == "") return null;

            using (StringReader sr = new StringReader(xmlCalendar))
            {
                XDocument xmlDoc = XDocument.Load(sr);
                sr.Close();
                return (from c in xmlDoc.Descendants("Calendar") select c.Value).ToArray<string>();
            }
        }

        #endregion

        #region 网格提示信息

        private void toolTipController1_GetActiveObjectInfo(object sender, DevExpress.Utils.ToolTipControllerGetActiveObjectInfoEventArgs e)
        {
            if (e.SelectedControl != guideStatusGridControl) return;

            ToolTipControlInfo info = null;
            try
            {
                GridView view = guideStatusGridControl.GetViewAt(e.ControlMousePosition) as GridView;
                if (view == null) return;
                GridHitInfo hi = view.CalcHitInfo(e.ControlMousePosition);

                if (hi.InRowCell)
                {
                    info = new ToolTipControlInfo(new CellToolTipInfo(hi.RowHandle, hi.Column, "cell"), GetCellHintText(view, hi.RowHandle, hi.Column));
                    return;
                }
            }
            finally
            {
                e.Info = info;
            }
        }
        private string GetCellHintText(GridView view, int rowHandle, DevExpress.XtraGrid.Columns.GridColumn column)
        {
            if (view.GetRowCellValue(rowHandle, column) == System.DBNull.Value || column.FieldName == "CiceroniName") return "";
            if (_dtGuideArrangeInfo == null) return "";

            StringBuilder retContext = new StringBuilder();
            string ciceroniId = view.GetRowCellValue(rowHandle, "CiceroniID").ToString();
            //string yMd = DateTime.Parse(string.Format("{0}-{1}-{2}", _CurrentSelectDate.Year, _CurrentSelectDate.Month, column.FieldName)).ToString("yyyy-MM-dd"); //string.Format("{0}-{1}-{2}", _CurrentSelectDate.Year, _CurrentSelectDate.Month, column.FieldName);
            string filterExpression = string.Format("StartDate<='{0}' AND '{0}'<=EndDate AND  CiceroniID={1}", column.FieldName, ciceroniId);
            DataRow[] drs = _dtGuideArrangeInfo.Select(filterExpression);
            if (drs.Length == 0)
                return "";
            else
            {
                for (int i = 0; i < drs.Length; i++)
                {
                    int hasEvent = int.Parse(drs[i]["HasEvent"].ToString());

                    retContext.AppendFormat("导游:{0}\r\n", drs[i]["CiceroniName"].ToString());
                    if (hasEvent == 1 || hasEvent == 5)//是事假或紧急事件
                    {
                        retContext.AppendFormat("计划号:{0}\r\n", drs[i]["TourgroupID"].ToString());
                        retContext.AppendFormat("是否通知:{0}\r\n", bool.Parse(drs[i]["Notified"].ToString()) == true ? "是" : "否");
                    }
                    retContext.AppendFormat("起止日期:{0}至{1}\r\n", drs[i]["StartDate"].ToString(), drs[i]["EndDate"].ToString());
                    retContext.AppendFormat("说明:{0}\r\n", drs[i]["Remark"].ToString());

                }
                return retContext.ToString();
            }
        }

        #endregion

        #region 网格事件处理

        /// <summary>
        /// 根据单元格的值自动设定单元格颜色状态
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void guideStatusGridView_RowCellStyle(object sender, DevExpress.XtraGrid.Views.Grid.RowCellStyleEventArgs e)
        {
            if (e.CellValue == null) return;

            switch (e.CellValue.ToString())
            {
                case "#1":
                case "1"://团安排导游
                    e.Appearance.BackColor = Color.Green;
                    break;
                case "#0":
                case "0"://导游事假
                    e.Appearance.BackColor = Color.Yellow;
                    break;
                case "#2":
                case "2"://导游一天内重复2次上团
                    e.Appearance.BackColor = Color.Blue;
                    break;
                case "#3":
                case "3"://导游一天内重复3次上团
                    e.Appearance.BackColor = Color.Brown;
                    break;
                case "#5":
                case "5":
                    e.Appearance.BackColor = Color.Red;
                    break;
                default:
                    break;
            }
        }
        private void guideStatusGridView_CustomDrawCell(object sender, RowCellCustomDrawEventArgs e)
        {
            //switch (e.CellValue.ToString())
            //{
            //    case "#0":
            //    case "#1":
            //    case "#2":
            //    case "#3":
            //        //e.Appearance.Image = Properties.Resources.bz;
            //        //e.Appearance.Image = Image.FromHbitmap(new Icon(@"C:\Users\SangYH\Desktop\check.ico").ToBitmap().GetHbitmap());
            //        break;
            //    default:
            //        break;

            //}
        }
        private void guideStatusGridView_SelectionChanged(object sender, DevExpress.Data.SelectionChangedEventArgs e)
        {
            //第一列不允许选择
            GridCell[] selectedCells = guideStatusGridView.GetSelectedCells();
            foreach (GridCell cell in selectedCells)
            {
                if (cell.Column.FieldName == "CiceroniName")
                    guideStatusGridView.UnselectCell(cell);
            }
        }

        private void guideStatusGridView_RowClick(object sender, RowClickEventArgs e)
        {
            if (e.Clicks == 2 && _dtGuideArrangeInfo != null)
            {
                string ciceroniId = guideStatusGridView.GetRowCellValue(guideStatusGridView.FocusedRowHandle, "CiceroniID").ToString();

                //string yMd = DateTime.Parse(string.Format("{0}-{1}-{2}", _CurrentSelectDate.Year, _CurrentSelectDate.Month, guideStatusGridView.FocusedColumn.FieldName)).ToString("yyyy-MM-dd");
                string yMd = guideStatusGridView.FocusedColumn.FieldName;
                string filterExpression = string.Format("StartDate<='{0}' AND '{0}'<=EndDate AND  CiceroniID={1}", yMd, ciceroniId);
                DataRow[] drs = _dtGuideArrangeInfo.Select(filterExpression);
                if (drs.Length > 0)
                    new GuideStatusLookupTourgroup(drs).ShowDialog(this);
            }
        } 

        #endregion

         private void btnBack_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            _StartDate = _StartDate.AddDays(-1);
            _EndDate = _EndDate.AddDays(-1);

            LoadGuideArrangeLayout();
        }

        private void btnForward_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            _StartDate = _StartDate.AddDays(1);
            _EndDate = _EndDate.AddDays(1);

            LoadGuideArrangeLayout();
        }

    }
}
